<template>
  <div ref="mapRef" class="map"></div>
</template>
<script setup>
import {
  defineProps,
  defineExpose,
  onMounted,
  ref,
  defineEmits
} from 'vue';
import { getCarTrack } from '@/api/car/index.js';
import LocationUtil from '@/utils/LocationUtil.js';
// 组件属性
const props = defineProps({
  startTime: {
    type: Number,
    required: true
  },
  endTime: {
    type: Number,
    required: true
  },
  vin:{
    type: String,
    default: undefined
  },
  tableType:{
    type: Number,
    default: undefined
  }
});
const mapRef = ref(null);
let map;

// 加载底图
const loadMap = () => {
  map = new Cesium.Viewer(mapRef.value, {
    useDefaultRenderLoop: true, // 是否自动渲染
    geocoder: false, // 地理位置查询定位控件
    homeButton: false, // 默认相机位置控件
    timeline: true, // 时间滚动条控件
    navigationHelpButton: false, // 默认的相机控制提示控件
    fullscreenButton: false, // 全屏控件
    baseLayerPicker: false, // 底图切换控件
    animation: false, // 控制场景动画的播放速度控件
    selectionIndicator: false, // 取消双击追踪实体行为
    requestRenderMode: false, // 如果为 true，则仅在场景中的变化所确定的需要时才会渲染帧。
    // maximumRenderTimeChange: Infinity, // 如果requestRenderMode为true，这个值定义了在请求渲染之前允许的模拟时间的最大变化。
    sceneModePicker: false, // 不创建SceneModePicker小部件。
    infoBox: false, // 不创建 InfoBox 小部件。
    navigationInstructionsInitiallyVisible: false, // 如果导航说明最初应该是可见的，则为真，如果在用户明确单击按钮之前不应显示，则为假。
    imageryProvider: new Cesium.UrlTemplateImageryProvider({
      url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png ',
      subdomains: ['a', 'b', 'c', 'd']
    }), // 初始化默认球皮
    shouldAnimate: true, // 用于开启时钟视图模型
    // sceneMode: Cesium.SceneMode.COLUMBUS_VIEW,
    showRenderLoopErrors: false, // 是否显示错误弹框
    orderIndependentTranslucency: true // 如果为 true 且配置支持，则使用与顺序无关的半透明。
  });
  // 开启抗锯齿
  map.scene.postProcessStages.fxaa.enabled = true;
  // js版本存在判断是否支持图像渲染像素化处理，目前不存在。后续可让用于自定义传入
  if (Cesium.defined(window.devicePixelRatio)) {
    // 设置屏幕分辨率尺度，解决渲染锯齿严重问题
    map.resolutionScale = window.devicePixelRatio;
  }
  // 移除双击追踪事件
  map.cesiumWidget.screenSpaceEventHandler.removeInputAction(
    Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
  );
  /**
   *  在测试是否与地形发生碰撞之前，摄像机必须达到的最小高度。 此参数在旋转角度时，
   *  若当前高度大于此高度会根据数据移动点y轴计算渲染
   */
  map.scene.screenSpaceCameraController.minimumCollisionTerrainHeight = 1;
  // 修改操作模式左键平移、中键缩放、右键旋转
  map.scene.screenSpaceCameraController.zoomEventTypes = [
    Cesium.CameraEventType.WHEEL,
    Cesium.CameraEventType.PINCH
  ];
  map.scene.screenSpaceCameraController.tiltEventTypes = [
    Cesium.CameraEventType.PINCH,
    Cesium.CameraEventType.RIGHT_DRAG
  ];
  // 隐藏Cesium icon显示
  map.cesiumWidget.creditContainer.setAttribute('style', 'display:none');
  // 无论是否开启动画,隐藏Cesium动画控件
  const animationElements = document.getElementsByClassName(
    'cesium-viewer-animationContainer'
  );
  if (Cesium.defined(animationElements) && animationElements.length > 0) {
    animationElements[0].setAttribute('style', 'display:none');
  }
  // 无论是否开启时间轴,隐藏Cesium时间轴控件
  const timelineElements = document.getElementsByClassName(
    'cesium-viewer-timelineContainer'
  );
  if (Cesium.defined(timelineElements) && timelineElements.length > 0) {
    timelineElements[0].setAttribute('style', 'display:none');
  }
  map.scene.screenSpaceCameraController.maximumZoomDistance = 6045564;
  map.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(
      107.83707222607283,
      32.48847550608798,
      5045563.2196705565
    )
  });
};
let entity;
const query = async () => {
  if(entity) map.entities.remove(entity);
  let {vin, tableType, startTime, endTime} = props;
  if(!vin || !startTime || !endTime) return;
  if(tableType == undefined) tableType = parseInt(vin.charAt(0)) == NaN ? 1:2;
  const params = {
    vin,
    tableType,
    startTime,
    endTime
  };
  let { data } = await getCarTrack(params);
  const length = data.length;
  if (!length || length < 2) return;

  const start = Cesium.JulianDate.fromDate(new Date(data[0].timestamp));
  const stop = Cesium.JulianDate.fromDate(
    new Date(data[length - 1].timestamp)
  );
  map.clock.startTime = start.clone();
  map.clock.stopTime = stop.clone();
  map.clock.currentTime = start.clone();
  map.clock.clockRange = Cesium.ClockRange.CLAMPED;
  map.clock.multiplier = 1;
  map.clock.shouldAnimate = false;

  map.timeline.zoomTo(start, stop);
  const spp = new Cesium.SampledPositionProperty();
  const orien = new Cesium.SampledProperty(Cesium.Quaternion);
  const positions = []
  data.forEach(({ timestamp, latitude, longitude, heading }) => {
    const time = Cesium.JulianDate.fromDate(new Date(timestamp));
    const c3 = Cesium.Cartesian3.fromDegrees(longitude, latitude, 0);
    spp.addSample(time, c3);
    positions.push([longitude, latitude]);
    // heading = heading<=90?(heading+90):(heading >180&& heading<270)?(heading -180):(heading - 90)
    const o = Cesium.Transforms.headingPitchRollQuaternion(
      c3,
      new Cesium.HeadingPitchRoll(
        Cesium.Math.toRadians(heading - 90),
        Cesium.Math.toRadians(0),
        Cesium.Math.toRadians(0)
      )
    )
    orien.addSample(time, o);
  })
  const vop = new Cesium.VelocityOrientationProperty(spp);
  entity = map.entities.add({
    availability: new Cesium.TimeIntervalCollection([
      new Cesium.TimeInterval({
        start: start,
        stop: stop
      })
    ]),
    position: spp,
    orientation: tableType == 1?vop:orien,
    model: {
      uri: './data/car.gltf',
      minimumPixelSize: 64
    },
    path: {
      resolution: 1,
      material: Cesium.Color.fromCssColorString('#4E8CDC'),
      width: 4
    }
  });
  LocationUtil.flyToGeometry(map, positions, 1.5);
  setTimeout(()=>{
    map.clock.shouldAnimate = true;
  },8000)
};

/** 组件挂载后事件回调 */
onMounted(() => {
  loadMap();
});

defineExpose({
  query
});
</script>
<style scoped>
.map {
  width: 100%;
  height: calc(100% - 50px);
  position: absolute;
  left: 0;
  top: 50px;
}
</style>
